import { checkAllCart, deleteCart, findCartList, getNewCartGoods, insertCart, mergeLocalCart, updateCart } from '@/api/cart'

// 购物车模块
export default {
  namespaced: true,
  state () {
    return {
      list: []
    }
  },
  getters: {
    // 有效商品列表
    validList (state) {
      // 有效商品：库存>0,stock 商品有效标识为 true isEffective
      return state.list.filter(goods => goods.stock > 0 && goods.isEffective)
    },
    // 有效商品总件数
    validTotal (state, getters) {
      return getters.validList.reduce((p, c) => p + c.count, 0)
    },
    // 有效商品总金额
    validAmount (state, getters) {
      return getters.validList.reduce((p, c) => p + Math.round(c.nowPrice * 100) * c.count, 0) / 100
    },
    // 无效商品列表
    invalidList (state) {
      return state.list.filter(goods => goods.stock <= 0 || !goods.isEffective)
    },
    // 已选商品列表
    selectedList (state, getters) {
      return getters.validList.filter(item => item.selected)
    },
    // 已选商品总件数
    selectedTotal (state, getters) {
      return getters.selectedList.reduce((p, c) => p + c.count, 0)
    },
    // 已选商品总金额 Math.round 四舍五入
    selectedAmount (state, getters) {
      return getters.selectedList.reduce((p, c) => p + Math.round(c.nowPrice * 100) * c.count, 0) / 100
    },
    // 是否全选
    isCheckAll (state, getters) {
      return getters.validList.length !== 0 && getters.selectedList.length === getters.validList.length
    }
  },

  // 本地：id skuId name picture price nowPrice count attrsText selected stock isEffective
  // 线上：比上面多 isCollect 收藏字段  discount 折扣字段 两项信息 在未登录情况下不需要这两项
  mutations: {
    insertCart (state, payload) {
      // 约定加入购物车字段必须和后端保持一致 payload对象 的字段
      // 它们是：id skuId name attrsText picture price nowPrice selected stock count isEffective
      // 插入数据规则：
      // 1. 先找下是否有相同商品
      // 2. 如果有相同的商品，先查询它的数量，累加到payload上，再保存最新位置，原来商品需要删除
      // 3. 如果没有相同商品，保存在最新位置即可
      const sameIndex = state.list.findIndex(goods => goods.skuId === payload.skuId)
      // 逻辑：有相同的给payload累加数量，删除相同skuId的商品
      if (sameIndex >= 0) {
        payload.count = state.list[sameIndex].count + payload.count
        // 删除原来
        state.list.splice(sameIndex, 1)
      }
      // 追加新的
      state.list.unshift(payload)
    },
    // 修改购物车商品
    updateCart (state, goods) {
      // goods 商品信息: nowPrice stock isEffective
      // goods 商品对象的字段不固定, 对象中油那些字段就改哪些字段
      const updateGoods = state.list.find(item => item.skuId === goods.skuId)
      for (const key in goods) {
        if (goods[key] !== null && goods[key] !== undefined && goods[key] !== '') {
          updateGoods[key] = goods[key]
        }
      }
    },
    // 删除购物车商品
    deleteCart (state, skuId) {
      const index = state.list.findIndex(item => item.skuId === skuId)
      state.list.splice(index, 1)
    },
    // 设置购物车列表 登录后使用的
    setCartList (state, list) {
      state.list = list
    }
  },
  // 需要向后台加载数据，所以需要actions函数获取数据
  actions: {
    // 加入购物车
    insertCart (ctx, payload) {
      return new Promise((resolve, reject) => {
        // ctx.rootState 是获取根state对象，通过根state对象去取模块user中的数据
        if (ctx.rootState.user.profile.token) {
          // 已登录状态TODO
          insertCart(payload).then(() => {
            return findCartList()
          }).then((data) => {
            ctx.commit('setCartList', data.result)
            resolve()
          })
        } else {
          // 未登录状态
          ctx.commit('insertCart', payload)
          resolve()
        }
      })
    },
    // 获取商品列表
    findCartList (ctx) {
      return new Promise((resolve, reject) => {
        if (ctx.rootState.user.profile.token) {
          // 已登录
          findCartList().then(data => {
            ctx.commit('setCartList', data.result)
            resolve()
          })
        } else {
          // 未登录
          // 同时发送请求（有几个商品发几个请求） 等所有请求成功，一并去修改本地数据
          // Promise.all（promise数组）.then((dataList) => {}) 同时发请求，成功之后得到所有成功结果
          // Promise.resolve() Promise.reject() newPromise()
          // Promise.race(promise数组).then((data) => {}) 同时发请求，最快的请求成功，得到请求结果
          const promiseArr = ctx.state.list.map(item => {
            return getNewCartGoods(item.skuId)
          })
          // dataArr 成功结果的集合，数据顺序和promiseArr顺序一致，他又是根据state.list而来
          Promise.all(promiseArr).then(dataArr => {
            dataArr.forEach((data, i) => {
              ctx.commit('updateCart', { skuId: ctx.state.list[i].skuId, ...data.result })
            })
            // resolve()代表操作成功
            resolve()
          }).catch(e => {
            reject(e)
          })
        }
      })
    },
    // 删除购物车商品
    deleteCart (ctx, payload) {
      return new Promise((resolve, reject) => {
        if (ctx.rootState.user.profile.token) {
          // 已登录
          deleteCart([payload]).then(() => {
            return findCartList()
          }).then((data) => {
            ctx.commit('setCartList', data.result)
            resolve()
          })
        } else {
          // 未登录
          // 单条删除payload就是skuId
          ctx.commit('deleteCart', payload)
          resolve()
        }
      })
    },
    // 修改购物车商品(支持状态修改和数量修改)
    updateCart (ctx, payload) {
      return new Promise((resolve, reject) => {
        if (ctx.rootState.user.profile.token) {
          // 已登录
          updateCart(payload).then(() => {
            return findCartList()
          }).then((data) => {
            ctx.commit('setCartList', data.result)
            resolve()
          })
        } else {
          // 未登录
          // payload 需要skuId, 可能是select或者count
          ctx.commit('updateCart', payload)
          resolve()
        }
      })
    },
    // 做有效商品的全选或反选
    checkAllCart (ctx, selected) {
      return new Promise((resolve, reject) => {
        if (ctx.rootState.user.profile.token) {
          // 已登录
          const ids = ctx.getters.validList.map(item => item.skuId)
          checkAllCart({ selected, ids }).then(() => {
            return findCartList()
          }).then((data) => {
            ctx.commit('setCartList', data.result)
            resolve()
          })
        } else {
          // 未登录
          // 获取有效的商品列表，遍历的去调用修改mutations即可
          ctx.getters.validList.forEach(goods => {
            ctx.commit('updateCart', { skuId: goods.skuId, selected })
          })
          resolve()
        }
      })
    },
    // 批量删除选中商品 或者清空无效商品
    batchDeleteCart (ctx, isClear) {
      return new Promise((resolve, reject) => {
        if (ctx.rootState.user.profile.token) {
          // 已登录
          // 得到需要删除的商品列表(失效，选中)的skuId集合
          const ids = ctx.getters[isClear ? 'invalidList' : 'selectedList'].map(item => item.skuId)
          deleteCart(ids).then(() => {
            return findCartList()
          }).then((data) => {
            ctx.commit('setCartList', data.result)
            resolve()
          })
        } else {
          // 未登录
          // 获取选中商品列表，进行遍历调用deleteCart mutations函数
          // isClear 为 true 删除失效商品，否则是删除选中商品列表
          ctx.getters[isClear ? 'invalidList' : 'selectedList'].forEach(goods => {
            ctx.commit('deleteCart', goods.skuId)
          })
          resolve()
        }
      })
    },
    // 修改购物车中商品的规格属性
    updateCartSku (ctx, { oldSkuId, newSku }) {
      return new Promise((resolve, reject) => {
        if (ctx.rootState.user.profile.token) {
          // 已登录
          // 当你修改了sku的时候其实skuId需要更改，相当于把原来的信息移出，创建一条新的商品信息
          // 先获取旧的商品
          const oldGoods = ctx.state.list.find(item => item.skuId === oldSkuId)
          // 再删除这条旧的商品
          deleteCart([oldSkuId]).then(() => {
            return insertCart({ skuId: newSku.skuId, count: oldGoods.count })
          }).then(() => {
            return findCartList()
          }).then((data) => {
            ctx.commit('setCartList', data.result)
            resolve()
          })
        } else {
          // 未登录
          // 当你修改了sku的时候其实skuId需要更改，相当于把原来的信息移出，创建一条新的商品信息
          // 先获取旧的商品
          const oldGoods = ctx.state.list.find(item => item.skuId === oldSkuId)
          // 再删除这条旧的商品
          ctx.commit('deleteCart', oldSkuId)
          // 然后合并一条新的商品信息
          const { skuId, price: nowPrice, inventory: stock, specsText: attrsText } = newSku
          const newGoods = { ...oldGoods, skuId, nowPrice, stock, attrsText }
          // 重新添加到购物车
          ctx.commit('insertCart', newGoods)
          resolve()
        }
      })
    },
    // 登录后合并购物车
    async mergeLocalCart (ctx) {
      // 准备合并的参数
      const cartList = ctx.getters.validList.map(({ skuId, selected, count }) => {
        return { skuId, selected, count }
      })
      await mergeLocalCart(cartList)
      ctx.commit('setCartList', [])
    }
  }
}
